/*
 * Created: Author: Aléx Carvalho / Date: May 16, 2015
 * 
 * Changed: $Author: ac280593@gmail.com $ / $Date: 2015-06-11 01:31:49 -0300 (Thu, 11 Jun 2015) $
 */
package com.cpm.view.zk.editors;

import com.cpm.view.zk.parts.Window;
import com.cpm.context.SystemLogger;
import com.cpm.view.EditorCallback;
import com.cpm.view.Icon;
import com.cpm.view.IconKit;
import com.cpm.view.zk.MenuAction;
import com.cpm.wrapper.SolidObjects;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;

public class AbstractEditor<T> extends Window {

    protected final T clone;
    private final EditorCallback<T> editorCallback;

    private final List<EditorPanel> editorPanels = new ArrayList<>(0);

    public AbstractEditor(T source, EditorCallback<T> editorCallback) {
        SolidObjects.notNullValues(source, editorCallback);

        this.clone = SolidObjects.notNull(cloneSource(source));
        this.editorCallback = editorCallback;
    }

    public void getMenuActions(LinkedHashSet<MenuAction> menuActions) {
        MenuAction cancel = new MenuAction(new Icon(IconKit.CANCEL), "Sair do modo de edição", (e) -> cancel());
        MenuAction accept = new MenuAction(new Icon(IconKit.OK), "Salvar alterações", (e) -> accept());

        menuActions.add(cancel);
        menuActions.add(accept);
    }

    private void cancel() {
        editorCallback.cancel();
        detach();
    }

    private void accept() {
        validateInput();
        updateSource();
        editorCallback.accept(clone);

        //TODO: mensagem de comfirmação
    }

    private void validateInput() {
        editorPanels.forEach( (EditorPanel p) -> p.validateInput() );
    }

    private void updateSource() {
        editorPanels.forEach( (EditorPanel p) -> p.updateSource() );
    }

    public void addPanel(EditorPanel<T> editorPanel) {
        editorPanels.add(editorPanel);
        
        editorPanel.setSource(clone);
        appendChild(editorPanel.getElement());
    }

    private T cloneSource(T value) {
        try {
            return (T) SolidObjects.notNull(value).getClass().getMethod("clone").invoke(value);
        }
        catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
            SystemLogger.printException(ex);
        }

        return null;
    }
}
